/**
 * 
 */
package jacek.kowalczyk.internal;

import java.awt.Dimension;
import java.awt.Font;
import java.awt.GridBagConstraints;
import java.awt.GridBagLayout;
import java.awt.GridLayout;
import java.awt.HeadlessException;
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;
import java.awt.event.MouseEvent;
import java.awt.event.MouseListener;
import java.io.BufferedReader;
import java.io.BufferedWriter;
import java.io.File;
import java.io.FileNotFoundException;
import java.io.FileReader;
import java.io.FileWriter;
import java.io.IOException;
import java.util.Date;

import javax.swing.JButton;
import javax.swing.JDialog;
import javax.swing.JFrame;
import javax.swing.JLabel;
import javax.swing.JTextArea;
import javax.swing.JTextField;


/**
 * @author kowalczy
 *
 */
public class GridBag extends JFrame {
    
    public final long workDay = 8 * 60 * 60 * 1000 + 30 * 60 * 1000;
    public long leftTime;
    private JTextArea informationTextField;
    private boolean exit = false;
    private String leftTimeLabelText;
    private JButton pauseResumeButton;
    private JButton dumpButton;
    private boolean pause = false;
    private MouseListener trackerContextMenu;
    private JLabel statusLabel;
    private Font textFont;
    private long elapsedTime;
    private JLabel elapsedTimeLabel;
    private Date targetDate;
    
    private static String dumpFilePath = "timetracker.dmp";
    private Date startDate;
    private JButton loadButton;

    /**
     * @return the leftTime
     */
    public long getLeftTime() {
        return leftTime;
    }

    /**
     * @param leftTime the leftTime to set
     */
    public synchronized void setLeftTime(long leftTime) {
        this.leftTime = leftTime;
    }

    /**
     * @return the elapsedTime
     */
    public long getElapsedTime() {
        return elapsedTime;
    }

    /**
     * @param elapsedTime the elapsedTime to set
     */
    public synchronized void setElapsedTime(long elapsedTime) {
        this.elapsedTime = elapsedTime;
    }

    
    public GridBag() throws HeadlessException {
        super();
        this.informationTextField = new JTextArea("");
        this.informationTextField.setEditable(false);
        this.informationTextField.setLineWrap(true);
        this.informationTextField.setRows(5);
        this.exit = false;
        this.leftTimeLabelText = "";
        this.leftTime = (long)this.workDay;
        this.pauseResumeButton = new JButton("Pause/Resume");
        this.dumpButton = new JButton("Dump state");
        this.loadButton = new JButton("Load state");
        this.statusLabel = new JLabel("Status: Time is ticking");
        this.textFont = new Font("Tahoma-Plain-18", Font.BOLD, 18); // NOI18N
        this.elapsedTime = 0L;
        this.elapsedTimeLabel = new JLabel("Elapsed time:\n");

        this.targetDate = new Date();
        Date now = new Date();

        this.targetDate.setTime(now.getTime() + workDay);
        this.startDate = new Date();

    }

    class BackgroundThread implements Runnable {

        // private Date targetDate;
        // private String leftTimeLabelText = "dd days hh hours mm minutes";
        // private boolean exit = false;
        private int progresCounter = 0;

        public void run() {
            String progres = "";
            String progresText0 = "background thread remaining time ";
            System.out.println(progresText0);
            // try {
            // System.out.println(progresText0);
            // } catch (IOException e1) {
            // // TODO Auto-generated catch block
            // e1.printStackTrace();
            // }
            while (!exit) {
                try {

                    // if (getLeftTime() <= 0) {
                    // leftTimeLabelText = "I is time to go home !!! :-)";
                    // } else {

                    leftTimeLabelText = "Remaining time:\n " + getHoursMinutesText(leftTime);

                    String progresText1 = " " + leftTime + " = " + getHoursMinutesText(leftTime);
                    String progresText2 = "background thread " + leftTimeLabelText;
                    //                        

                    try {
                        // System.out.println(progresText +"\r".getBytes("UTF-8"));
                        // System.out.print("remaining time " + leftTime );
                        System.out.write((byte)'\r');
                        System.out.write(progresText1.getBytes());
                        // System.out.write(getHoursMinutesText(leftTime).getBytes());
                        // System.out.write(13);

                    } catch (IOException e) {
                        // TODO Auto-generated catch block
                        e.printStackTrace();
                    }

                    informationTextField.setText(leftTimeLabelText);
                    informationTextField.setFont(textFont); // NOI18N
                    informationTextField.repaint();

                    elapsedTimeLabel.setText("Elapsed time:\n " + getHoursMinutesText(elapsedTime));
                    elapsedTimeLabel.repaint();
                    // jCheckBox1.repaint();
                    if (isPause()) {
                        Date now = new Date();
                        long milisecondsNow = now.getTime();
                        targetDate.setTime(milisecondsNow + getLeftTime());

                    } else {

                        Date now = new Date();
                        long milisecondsNow = now.getTime();
                        //if (getLeftTime() >= 0) {
                            setLeftTime((long)targetDate.getTime() - milisecondsNow);
                        //}
                        setElapsedTime(milisecondsNow - startDate.getTime());

                        if (progresCounter == 10) {
                            progres = "";
                            progresCounter = 0;
                        }
                        // else if (progresCounter % 1000 == 0){
                        // progres = progres + ".";
                        // }
                        else {
                            progres = progres + ".";
                        }
                        progresCounter++;
                        statusLabel.setText("Status: Time is ticking " + progres);
                        statusLabel.repaint();
                    }
                    // }///else

                    // Thread.sleep(60000);//1 minute
                    Thread.sleep(1000);// 1 mili second
                } catch (InterruptedException ex) {
                    ex.printStackTrace();
                }
            }

        }
    }

    /**
     * @param args
     */
    public static void main(String[] args) {
        // TODO Auto-generated method stub
        GridBag tt = new GridBag();
        if (args.length >= 1) {
            tt.leftTime = tt.initTime(args[0]);
        }

        tt.initComponents();
        tt.initBackground();

        tt.setVisible(true);
    }

    protected void setPause(boolean b) {
        this.pause = b;

    }

    protected boolean isPause() {
        return this.pause;
    }

    public static String getHoursMinutesText(long milisecTime) {
        long hours = milisecTime / (1000 * 60 * 60);
        long lastHourTime = milisecTime % (1000 * 60 * 60);
        long minutes = lastHourTime / (1000 * 60);
        return " " + hours + " hours " + minutes + " minutes";

    }

    public static long getHours(long milisecTime) {
        long hours = milisecTime / (1000 * 60 * 60);
        // long lastHourTime = milisecTime % (1000 * 60 * 60);
        // long minutes = lastHourTime / (1000 * 60);
        return hours;
    }

    public static long getMinutes(long milisecTime) {
        long hours = milisecTime / (1000 * 60 * 60);
        long lastHourTime = milisecTime % (1000 * 60 * 60);
        long minutes = lastHourTime / (1000 * 60);
        return minutes;
    }

    public static long getMiliSeconds(long hours, long minutes) {
        long milisecunds = (long)(hours * 60 * 60 * 1000 + minutes * 60 * 1000);
        return milisecunds;
    }

    private void initComponents() {
        Dimension d = new Dimension(200, 200);

        setSize(d);
        setMaximumSize(d);
        setMinimumSize(d);
        setLocationRelativeTo(null);
        setResizable(false);
        setTitle("TimeTracker");
        setDefaultCloseOperation(EXIT_ON_CLOSE);
        GridBagLayout gbl = new GridBagLayout();
        setLayout(gbl);
        GridBagConstraints gbc = new GridBagConstraints();
        
        
        pauseResumeButton.addActionListener(new ActionListener() {

            public void actionPerformed(ActionEvent e) {
                if (isPause()) {
                    setPause(false);
                    pauseResumeButton.setText("Pause");
                    statusLabel.setText("Status: Time is ticking");
                } else {
                    setPause(true);
                    pauseResumeButton.setText("Resume");
                    statusLabel.setText("Status: Paused");
                }
            };
        });
        
        dumpButton.addActionListener(new ActionListener() {

            public void actionPerformed(ActionEvent e) {
                saveRemainingTime(dumpFilePath);
            };
        });
        
        loadButton.addActionListener(new ActionListener() {

            public void actionPerformed(ActionEvent e) {
                loadRemainingTime(dumpFilePath);
            };
        });
        
        trackerContextMenu = new MouseListener() {

            public void mouseReleased(MouseEvent e) {
                // TODO Auto-generated method stub

            }

            public void mousePressed(MouseEvent e) {
                // TODO Auto-generated method stub

            }

            public void mouseExited(MouseEvent e) {
                // TODO Auto-generated method stub

            }

            public void mouseEntered(MouseEvent e) {
                // TODO Auto-generated method stub

            }

            public void mouseClicked(MouseEvent e) {
                if (e.getButton() == MouseEvent.BUTTON1) {
                    showInitDialog();
                }

            }
        };
        informationTextField.addMouseListener(trackerContextMenu);
        gbc.fill = GridBagConstraints.HORIZONTAL;
        gbc.gridx = 0;
        gbc.gridy = 0;
        gbc.gridwidth = 2;
        getContentPane().add(informationTextField, gbc);

        gbc.fill = GridBagConstraints.HORIZONTAL;
        gbc.gridx = 0;
        gbc.gridy = 1;
        gbc.gridwidth = 2;
        
        getContentPane().add(elapsedTimeLabel, gbc);
        
        gbc.fill = GridBagConstraints.HORIZONTAL;
        gbc.gridx = 0;
        gbc.gridy = 2;
        gbc.gridwidth = 2;
        getContentPane().add(pauseResumeButton, gbc);
        
        gbc.fill = GridBagConstraints.NONE;
        gbc.gridx = 0;
        gbc.gridy = 3;
        gbc.weightx =0.5;
        gbc.gridwidth = 1;
        getContentPane().add(dumpButton, gbc);
        
        gbc.fill = GridBagConstraints.NONE;
        gbc.gridx = 1;
        gbc.gridy = 3;
        gbc.weightx =0.5;
        gbc.gridwidth = 1;
        getContentPane().add(loadButton, gbc);
        
        gbc.fill = GridBagConstraints.HORIZONTAL;
        gbc.gridx = 0;
        gbc.gridy = 4;
        gbc.weightx =1.0;
        gbc.gridwidth = 2;
        getContentPane().add(statusLabel, gbc);

    }

    protected void showInitDialog() {
        final JDialog initDialog = new JDialog(this);
        Dimension d = new Dimension(200, 150);

        initDialog.setSize(d);
        initDialog.setMaximumSize(d);
        initDialog.setMinimumSize(d);
        initDialog.setLocationRelativeTo(null);
        initDialog.setResizable(false);
        initDialog.setTitle("init TimeTracker");
        initDialog.setDefaultCloseOperation(JFrame.DISPOSE_ON_CLOSE);

        initDialog.setLayout(new GridLayout(5, 1));
        final JTextField initField = new JTextField("" + this.leftTime);
        final JTextField initHoursField = new JTextField("" + getHours(this.getLeftTime()));
        JLabel initHoursLabel = new JLabel("hours");
        final JTextField initMinutesField = new JTextField("" + getMinutes(this.getLeftTime()));
        JLabel initMinutesLabel = new JLabel("minutes");
        JButton initButton = new JButton("Set time ");
        initButton.addActionListener(new ActionListener() {

            public void actionPerformed(ActionEvent e) {
                long temp = leftTime;
                try {
                    // long time = initTime(initField.getText());
                    long h = initTime(initHoursField.getText());
                    long m = initTime(initMinutesField.getText());
                    long time = getMiliSeconds(h, m);
                    setLeftTime(time);

                } catch (NumberFormatException ex) {
                    ex.printStackTrace();
                    setLeftTime(temp);

                } finally {
                    Date now = new Date();
                    targetDate.setTime(now.getTime() + getLeftTime());

                    if (leftTime <= 0) {
                        leftTimeLabelText = "I is time to go home !!! :-)";
                    } else {
                        leftTimeLabelText = "Remaining time:\n " + getHoursMinutesText(leftTime);
                        System.out.println(leftTimeLabelText);
                        System.out.println("remaining time set from dialog " + leftTime + " ="
                            + getHoursMinutesText(leftTime));
                        System.out.println("background thread remaining time ");
                        informationTextField.setText(leftTimeLabelText);
                        informationTextField.setFont(textFont); // NOI18N
                        informationTextField.repaint();
                        initDialog.dispose();
                    }
                }

            }
        });
        initDialog.add(initHoursField);
        initDialog.add(initHoursLabel);
        initDialog.add(initMinutesField);
        initDialog.add(initMinutesLabel);

        // initDialog.add(initField);
        initDialog.add(initButton);
        initDialog.setVisible(true);
    }

    private void initBackground() {
        BackgroundThread job = new BackgroundThread();
        Thread worker = new Thread(job);
        worker.start();

    }

    private long initTime() {

        return workDay;
    }

    private long initTime(String remainingTime) {
        return Long.parseLong(remainingTime);

    }

    private String loadRemainingTime(String filePath) {
        String timeValue = "";
        File in ;
        FileReader fr;
        BufferedReader br;
        try{
            in = new File(filePath);
            fr = new FileReader(in);
            br = new BufferedReader(fr);
            String s = null;
            
            try{
            s= br.readLine();
            if (s!= null && s.length()>0){
                setLeftTime(Long.parseLong(s));
            }
            } catch (IOException e) {
                e.printStackTrace();
            }
            
        } catch (FileNotFoundException e){
            e.printStackTrace();
        }
        return timeValue;
    }

    private boolean saveRemainingTime(String filePath) {
        File out;
        FileWriter fw ;
        BufferedWriter bw;
        try {
            out = new File (filePath);
            fw =  new FileWriter(out);
            bw = new BufferedWriter(fw);
            
            bw.write(""+this.getLeftTime());
            bw.close();
            return true;
            
        } catch (FileNotFoundException e) {
            // TODO Auto-generated catch block
            e.printStackTrace();
            return false;
        } catch (IOException e) {
            // TODO Auto-generated catch block
            e.printStackTrace();
            return false;
        }
        
        
    }
    }
    
